package cron

import (
	"base/conf"
	"base/util/slog"
	"fmt"
	"github.com/robfig/cron/v3"
	"os"
	"os/signal"
	"reflect"
	"syscall"
)

//定义控制器函数Map类型，便于后续快捷使用
type ControllerMapsType map[string]reflect.Value

var Schedule *cron.Cron

//声明控制器函数Map类型变量
var TaskList = make(ControllerMapsType, 0)

func init() {
	Schedule = cron.New()
	var Tasks Tasks
	vf := reflect.ValueOf(&Tasks)
	vft := vf.Type()
	//读取方法数量
	mNum := vf.NumMethod()
	//遍历路由器的方法，并将其存入控制器映射变量中
	for i := 0; i < mNum; i++ {
		mName := vft.Method(i).Name
		TaskList[mName] = vf.Method(i)
	}
}

type Job struct {
	Name string
	Desc string
}

func init()  {
	conf.Conf.Logs.Name = "task"
}

func (job Job) Run() {
	if _, ok := TaskList[job.Name]; ok {
		slog.Logger.Info(fmt.Sprintf("[%s]任务开始", job.Name))
		TaskList[job.Name].Call(nil)
		slog.Logger.Info(fmt.Sprintf("[%s]任务完成", job.Name))
	} else {
		slog.Logger.Error(fmt.Sprintf("[%s]任务方法不存在，请检查配置文件", job.Name))
	}
}

func Run() {
	for _, t := range conf.Conf.Tasks {
		job := Job{Name: t.Name, Desc: t.Desc}
		_, err := Schedule.AddJob(t.Cron, job)
		if err != nil {
			slog.Logger.Error(err)
		}
	}
	Schedule.Start()
	signalProcess()
	select {}
}

func signalProcess() {
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
	go func() {
		for {
			sig := <-sigs
			switch sig {
			default:
				os.Exit(0)
			}
		}
	}()
}
